﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interpreter
{
	public class InlineValueBuilder
	{
		private List<string> stringTable = new List<string>();
		private List<int> integerTable = new List<int>();
		private List<double> floatTable = new List<double>();
		private List<string> idTable = new List<string>();

		public void AddString(string value)
		{
			this.stringTable.Add(value);
		}

		public void AddInteger(int value)
		{
			this.integerTable.Add(value);
		}

		public void AddDouble(double value)
		{
			this.floatTable.Add(value);
		}

		public void AddId(string value)
		{
			this.idTable.Add(value);
		}

		public string[] GetStringTable()
		{
			return this.stringTable.ToArray();
		}

		public int[] GetIntegerTable()
		{
			return this.integerTable.ToArray();
		}

		public double[] GetFloatTable()
		{
			return this.floatTable.ToArray();
		}

		public string[] GetIdTable()
		{
			return this.idTable.ToArray();
		}

		public InlineValueBuilder(string inlineValuesRawString)
		{
			string[] pieces = Util.BreakString(inlineValuesRawString, 4);
			string stringTable = pieces[0];
			string integerTable = pieces[1];
			string floatTable = pieces[2];
			string idTable = pieces[3];

			this.InitializeStringTable(stringTable);
			this.InitializeIntegerTable(integerTable);
			this.InitializeFloatTable(floatTable);
			this.InitializeIdTable(idTable);
		}

		private void InitializeIdTable(string rawIdTable)
		{
			string[] ids = rawIdTable.Split('^');
			foreach (string id in ids)
			{
				this.AddId(id);
			}
		}

		private void InitializeIntegerTable(string rawIntegerTable)
		{
			string[] numbers = rawIntegerTable.Split('^');
			foreach (string number in numbers)
			{
				this.AddInteger(Util.ConvertFromHex(number));
			}
		}

		private void InitializeFloatTable(string rawFloatTable)
		{
			string[] numbers = rawFloatTable.Split('^');
			foreach (string number in numbers)
			{
				string[] parts = number.Split('E');
				double b = double.Parse(parts[0]);
				double exponent = int.Parse(parts[1]);
				double value = b * System.Math.Pow(10, exponent);

				this.AddDouble(value);
			}
		}

		private void InitializeStringTable(string rawStringTable)
		{
			int index = 0;
			int length = rawStringTable.Length;
			char c;
			while (index < length)
			{
				string entryLength = "";
				do
				{
					c = rawStringTable[index];
					if (c != '^')
					{
						entryLength += c;
					}
					++index;
				} while (c != '^');

				StringBuilder entry = new StringBuilder();
				int end = index + Util.ConvertFromHex(entryLength) * 2;
				while (index < end)
				{
					c = (char)(byte)Util.ConvertFromHex("" + rawStringTable[index] + rawStringTable[index + 1]);
					entry.Append(c);
					index += 2;
				}
				this.AddString(entry.ToString());
			}
		}
	}
}
